﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using l1cs.server.model.Instance;

namespace l1cs.server.clientpackets
{
    public abstract class ClientBasePacket
    {
        private static Logger _log = Logger.getLogger( typeof( ClientBasePacket ).FullName );

        private static String CLIENT_LANGUAGE_CODE = Config.CLIENT_LANGUAGE_CODE;

        private byte[] _decrypt;

        private int _off;

        public ClientBasePacket( byte[] abyte0 )
        {
            _log.finest( "type=" + getType() + ", len=" + abyte0.Length );
            _decrypt = abyte0;
            _off = 1;
        }

        //public ClientBasePacket(ByteBuffer bytebuffer, ClientThread clientthread)
        //{
        //}

        public int readD()
        {
            int i = _decrypt[_off++] & 0xff;
            i |= _decrypt[_off++] << 8 & 0xff00;
            i |= _decrypt[_off++] << 16 & 0xff0000;
            i |= (int)((long)_decrypt[_off++] << 24 & 0xff000000);
            return i;
        }

        public int readC()
        {
            int i = _decrypt[_off++] & 0xff;
            return i;
        }

        public int readH()
        {
            int i = _decrypt[_off++] & 0xff;
            i |= _decrypt[_off++] << 8 & 0xff00;
            return i;
        }

        public int readCH()
        {
            int i = _decrypt[_off++] & 0xff;
            i |= _decrypt[_off++] << 8 & 0xff00;
            i |= _decrypt[_off++] << 16 & 0xff0000;
            return i;
        }

        //public double readF()
        //{
        //    long l = _decrypt[_off++] & 0xff;
        //    l |= _decrypt[_off++] << 8 & 0xff00;
        //    l |= _decrypt[_off++] << 16 & 0xff0000;
        //    l |= _decrypt[_off++] << 24 & 0xff000000;
        //    l |= (long)_decrypt[_off++] << 32 & 0xff00000000L;
        //    l |= (long)_decrypt[_off++] << 40 & 0xff0000000000L;
        //    l |= (long)_decrypt[_off++] << 48 & 0xff000000000000L;
        //    l |= (long)_decrypt[_off++] << 56 & 0xff00000000000000L;
        //    return Double.longBitsToDouble(l);
        //}

        public String readS()
        {
            String s = null;

            //s = new String(_decrypt, _off, _decrypt.Length - _off, CLIENT_LANGUAGE_CODE);
            byte[] saki = new byte[_decrypt.Length - _off];
            Array.Copy( _decrypt, _off, saki, 0, saki.Length );
            s = Encoding.GetEncoding( CLIENT_LANGUAGE_CODE ).GetString( saki );
            s = s.Substring( 0, s.IndexOf( '\0' ) );
            _off += Encoding.GetEncoding( CLIENT_LANGUAGE_CODE ).GetBytes( s ).Length + 1;

            return s;
        }

        public byte[] readByte()
        {
            byte[] result = new byte[_decrypt.Length - _off];

            Array.Copy( _decrypt, _off, result, 0, _decrypt.Length - _off );
            //for ( int i = 0; i < _decrypt.Length; i++ )
            //{
            //    result[i] = _decrypt[_off + i];
            //}
            _off = _decrypt.Length;

            return result;
        }

        /**
         * クライアントパケットの種類を表す文字列を返す。("[C] C_DropItem" 等)
         */
        virtual
        public String getType()
        {
            return "[C] " + this.GetType().Name;
        }
    }
}